<script lang="ts" setup>
import type { RenderContent } from '@arco-design/web-vue/es/_utils/types'
import type { DnsLinesListItem, DnsStrategyListItem } from '@/apis/model/dns'
import { Message } from '@arco-design/web-vue'
import { IconDown, IconStar } from '@arco-design/web-vue/es/icon'
import {
  deleteDnsAuthorityGtmStrategyApi,
  getDnsAuthorityGtmStrategiesApi,
  getDnsAuthorityLinesApi,
  updateDnsAuthorityGtmStrategyApi,
} from '@/apis/modules/dns'
import { commonTableProps } from '@/utils/table'
import EditDrawer from './EditDrawer.vue'
import EditRemarkDialog from './EditRemarkDialog.vue'
import useConfig from './useConfig'

interface IProps {
  type: 1 | 2
}
const props = defineProps<IProps>()
const route = useRoute()
const linesData = ref<DnsLinesListItem[]>([])
const tableData = ref<DnsStrategyListItem[]>([])
provide('addressPoolType', props.type)
provide('linesData', linesData.value)
const queryParams = ref({
  line: undefined,
  instance_id: route.params.id,
  sort: 'created_at',
  order: 'desc',
})
const { searchSchema, tableColumns } = useConfig()
const {
  visible: editorRemarkDialogVisible,
  open: openEditorRemarkDialog,
  data: editorRemarkDialogData,
} = usePopup()

const {
  visible: editDrawerVisible,
  open: openEditDrawer,
  data: editDrawerData,
} = usePopup()

const { loading, run } = useListRequest(getDnsAuthorityGtmStrategiesApi, {
  params: queryParams,
  immediate: true,
  afterFn(res) {
    tableData.value = res.map(item => ({
      ...item,
      name: getLineDisplayName(
        item.line,
        linesData.value as DnsLinesListItem[],
      ),
      address_pool_sets: item.address_pool_sets.map(address => ({
        ...address,
        address_pools: address.address_pools.map(pool => ({
          ...pool,
          addresses: pool.addresses.map(v => ({
            ...v,
            name: v.ip,
          })),
        })),
      })),
    }))
  },
})
const { createSortChange } = useTable(run, tableData)
const onSorterChange = createSortChange(queryParams)
function shouldShowTooltip(remark: string) {
  if (!remark)
    return false
  return remark.length > 50 // 先按字符数快速判断
}
function handleBeforeChange(status: number, row: DnsStrategyListItem) {
  return new Promise((resolve, reject) => {
    updateDnsAuthorityGtmStrategyApi({ id: row.id, status } as any)
      .then(() => {
        row.status = row.status === 1 ? 2 : 1
        resolve(void 0)
      })
      .catch((err) => {
        reject(new Error(err?.message || '更新状态失败'))
      })
  })
}
function processArray(arr: DnsLinesListItem[]): DnsLinesListItem[] {
  return arr.map(item => ({
    ...item,
    children:
      item.children && item.children.length > 0
        ? processArray(item.children)
        : null,
  }))
}
// 获取所有线路
async function getDnsLines() {
  const res = await getDnsAuthorityLinesApi()
  linesData.value = processArray(res.list as DnsLinesListItem[])
}

// 删除策略
function handleDelete(record: DnsStrategyListItem) {
  ModalHelper.error({
    title: '删除策略',
    content: h('div', null, [
      '确定要删除请求来源为 “',
      h('span', { class: 'text-[#FA5566]' }, `${record.name || '-'}`),
      '” 的策略吗？',
    ]) as unknown as RenderContent,
    okText: '删除',
    width: 480,
    closable: false,
    onOk: async () => {
      await deleteDnsAuthorityGtmStrategyApi({ id: record.id })
      await run()
      Message.success('删除成功')
    },
  })
}
// 递归查找 返回display_name
function getLineDisplayName(
  code: string,
  lines: DnsLinesListItem[],
): string | undefined {
  const stack = [...lines]
  while (stack.length > 0) {
    const item = stack.pop()!
    if (item.code === code) {
      return item.display_name
    }
    if (item.children) {
      stack.push(...item.children)
    }
  }
  return undefined
}
onMounted(() => {
  getDnsLines()
})
</script>

<template>
  <section>
    <div class="my-6 flex items-center">
      <div class="flex space-x-4">
        <a-button
          type="primary"
          @click="openEditDrawer()"
        >
          新建策略
        </a-button>
        <a-cascader
          v-model="queryParams.line"
          :options="linesData"
          expand-trigger="hover"
          :field-names="{
            label: 'name',
            value: 'code',
            children: 'children',
          }"
          :style="{ width: '200px' }"
          placeholder="全部请求来源"
          allow-clear
          check-strictly
          @change="run()"
        />
        <multiple-condition-search
          v-model="queryParams"
          :schema="searchSchema"
          @search="run"
        />
      </div>
      <a-button
        class="ml-auto w-fit shrink-0 text-color-1"
        type="outline"
        :disabled="loading"
        @click="run"
      >
        <template #icon>
          <i-icons-refresh :class="{ 'animate-spin': loading }" />
        </template>
      </a-button>
    </div>
    <a-table
      v-bind="commonTableProps"
      :columns="tableColumns"
      :loading="loading"
      :data="tableData"
      @sorter-change="onSorterChange"
    >
      <template #address="{ record }">
        <a-popover
          v-for="(item, idx) in record.address_pool_sets"
          :key="item.id"
          trigger="click"
          position="right"
          content-class="max-h-[310px] min-w-50"
        >
          <span class="active-text">
            {{ item.name }}
            <span
              v-if="record.address_pool_sets.length - 1 !== idx"
              class="mx-1"
            >,</span>
          </span>
          <template #content>
            <a-tree
              :data="item.address_pools"
              block-node
              class="custom-tree"
              :field-names="{
                title: 'name',
                key: 'id',
                children: 'addresses',
              }"
              default-expand-all
            >
              <template #switcher-icon="_node, { isLeaf }">
                <icon-down v-if="!isLeaf" />
                <icon-star v-if="isLeaf" />
              </template>
            </a-tree>
          </template>
        </a-popover>
      </template>
      <template #remark="{ record }">
        <div class="flex">
          <a-tooltip
            :content="record.remark || '-'"
            position="top"
            :disabled="!shouldShowTooltip(record.remark)"
          >
            <span class="overflow-hidden text-ellipsis whitespace-nowrap">
              {{ record.remark || '-' }}
            </span>
          </a-tooltip>
          <div class="ml-1 min-w-4">
            <i-icons-edit
              class="table-icon"
              size="16px"
              @click="openEditorRemarkDialog(record)"
            />
          </div>
        </div>
      </template>
      <template #status="{ record }">
        <a-switch
          :model-value="record.status"
          :checked-value="1"
          :unchecked-value="2"
          size="small"
          :before-change="(val: number) => handleBeforeChange(val, record)"
        />
      </template>
      <template #actions="{ record }">
        <a-link
          :hoverable="false"
          @click="openEditDrawer(record)"
        >
          <i-icons-edit size="16px" />
        </a-link>
        <a-link
          :hoverable="false"
          status="danger"
          @click="handleDelete(record)"
        >
          <i-icons-delete size="16px" />
        </a-link>
      </template>
    </a-table>
    <edit-drawer
      v-model:visible="editDrawerVisible"
      :record="editDrawerData"
      :lines-data="linesData"
      @reload="run"
    />
    <edit-remark-dialog
      v-model:visible="editorRemarkDialogVisible"
      :record="editorRemarkDialogData"
      @reload="run"
    />
  </section>
</template>

<style lang="less">
.custom-tree {
  .arco-tree-node-is-leaf {
    .arco-tree-node-switcher {
      display: none !important;
    }
    .arco-tree-node-title-text {
      @apply text-xs text-[#86909C];
    }
  }
}
</style>

<style lang="less" scoped>
:deep(.arco-table-tr) {
  .active-text {
    @apply hover:border-b hover:border-[#00A65B] cursor-pointer;
  }
  .table-icon {
    opacity: 0;
    color: var(--color-text-7);
    cursor: pointer;
  }
  &:hover {
    .active-text {
      @apply text-[#00A65B];
    }
    .table-icon {
      opacity: 1;
      color: #00a65b;
    }
  }
}
:deep(.table-cascader) {
}
</style>
